package semaforo;

/*
 * En esta clase se representa un sem'aforo utilizando synchronized statements.
 * Se utilizar'an los metodos P() y V() vistos en clase.
 * Para poder sincronizar
 */
public class Semaforo {
	private int cantRecursos;
	private Object objetoSinc;
	
	/*El constructor toma por par'ametro la cantidad de recursos con los que cuenta.
	 * */
	public Semaforo(int cantRecursos){
		this.cantRecursos= cantRecursos;
		this.objetoSinc= new Object();
	}
	
	/*
	 * Este m'etodo es utilizado para poder acceder al objeto compartido. 
	 * Sino quedan mas recursos libres esperar'a a que se libere(comando wait) uno.
	 * Sincronizar la condici'on con el wait es necesario para evitar un lock.
	 */
	public synchronized void P(){
		cantRecursos --;
		System.out.println("P(). Cantidad de Recursos: "+ cantRecursos);
		
		synchronized (objetoSinc) {
			if (cantRecursos<0){
				try {
					System.out.println("El semaforo hace esperar al Thread.");
					objetoSinc.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}else{
				System.out.println("El semaforo no hace esperar al Thread.");
			}
			
		}
	}
	
	/*
	 * Este m'etodo es similar a P() solo que libera el recurso compartido. 
	 * Para avisar que se libero se utiliza el m'etodo notify(), esto solo se
	 * hace en caso de que haya un pedido.
	 */
	public synchronized void V(){
		cantRecursos++;
		System.out.println("V(). Cantidad de recursos: "+cantRecursos);
		
		synchronized (objetoSinc) {
			if(cantRecursos >= 0){
				objetoSinc.notify();
				System.out.println("Se nofica a los demas.");
			}else{
				System.out.println("no se notifica.");
			}
		}
	}

	public int getCantRecursos() {
		return cantRecursos;
	}
	

}
